import { useState, useEffect, useLayoutEffect } from 'react';
import { useParams } from 'react-router-dom';
import { observable } from '@formily/reactive';
import { observer } from '@formily/react';
import { RenderDropableWidget, useLayouts } from '@inbiz/react';
import { getEditor, debounce, changeAmin, InbizIcon, useInbizRouter, uuid } from '@inbiz/utils';
import { useGetMenuTreeEffect, globalAppInfo, useLayoutSize, useShareDataFlow } from '@inbiz/render';
import { InbizMenuProps } from '@common/InbizMenu/utils';
import { openUrl } from '@common/InbizMenu/service';
import { EdocMenu } from '@common/InbizMenu/common';
import './style.less';
import logo from '@assets/logo.svg'
import defaultSmall from '@assets/small-logo.svg'

interface MenuType {
  DataVersionId: string;
  DisplayName: string;
  Icon?: string;
  IsHaveChild: boolean;
  IsHomePage?: boolean;
  IsInternalLink?: boolean;
  IsTopNode?: boolean;
  LinkUrl?: string;
  Route: string;
  JumpRoute: string;
  OutId: string;
  ParentId?: string;
  Sort?: number;
  loadChildList?: any;
  placement?: any;
  inlineCollapsed?: any;
  showLevel: string[];
  jumpChild?: boolean;
  children?: MenuType[];
  menuOnClick?: Function;
  isSelect?: boolean;
  menu: {
    val: MenuType[];
    set: Function;
  };
  style?: any;
  isPre?: boolean;
  level: number;
  visible?: boolean;
  companentLevel: number;
  inbizMenu?: MenuType[];
}

const verticalMenuModel = observable({
  inlineCollapsed: false,
});

// 收缩框变化hooks
const useInlineCollapsed = (menuData?: Array<any>) => {
  const setInlineCollapsed = (val: boolean) => {
    verticalMenuModel.inlineCollapsed = val;
    const leftElement = document.querySelector(
      '.inbizWebPreview .dn-contentLayout .dn-workspace-panel',
    );
    if (leftElement) {
      if (menuData && menuData?.length > 0) {
        leftElement.setAttribute('style', `min-width:${val ? 60 : 180}px`);
      } else {
        leftElement.setAttribute('style', `min-width:0px`);
      }
    }
  };
  return [verticalMenuModel.inlineCollapsed, setInlineCollapsed] as [boolean, Function];
};

export const Vertical = observer((props: any) => {
  const {
    menuData,
    showlogo,
    viewtype,
    showLevel,
    menustyle,
    emit,
    mainmenu,
    jumpChild,
    isCollapse = true,
  } = props;

  const [inlineCollapsed] = useInlineCollapsed(menuData);
  const [layoutSize] = useLayoutSize();
  const [, $refresh] = useState('');
  const [height, $height] = useState(0);

  const { top, left, innerHeight } = layoutSize;
  const logoHeight = showlogo ? (!inlineCollapsed ? 120 : 104) : 60;
  const menuContent = left?.height || 0;
  const verticalHeight = !inlineCollapsed ? menuContent - logoHeight : menuContent - logoHeight;

  useEffect(() => {
    if (innerHeight) {
      $height(Math.abs(verticalHeight + (window.innerHeight - (innerHeight as number ?? 0))))
    }
  }, [verticalHeight, innerHeight])

  //根据窗口变化自适应高度
  useLayoutEffect(() => {
    const updateSize = debounce({
      fn: () => {
        if (innerHeight) {
          $height(Math.abs(verticalHeight + (window.innerHeight - (innerHeight as number ?? 0))))
        }
      },
      delay: 100,
    });
    window.addEventListener('resize', updateSize);
    return () => window.removeEventListener('resize', updateSize);
  }, []);

  return (
    <div className="vertical-menu-content">
      <div
        className='scrollbarHover'
        style={{
          height: height > 0 ? height : '100%',
          overflow: 'auto',
        }}
      >
        <EdocMenu
          menuData={menuData}
          iscolumn
          isCollapse={isCollapse}
          inlineCollapsed={inlineCollapsed}
          showLevel={showLevel}
          mainmenu={mainmenu}
          jumpChild={jumpChild}
          menustyle={menustyle}
          viewtype={viewtype}
          inbiz={props.inbiz}
          emit={emit}
        />
      </div>
    </div>
  );
});

export const VerticalMenu: any & {
  Plugin: React.ComponentProps<any>;
} = observer((props: InbizMenuProps) => {
  const {
    viewtype,
    showlogo,
    logoconfig,
    smallLogoconfig,
    shrinkage,
    displaytype,
    menustyle,
    showLevel,
    linkcomponent,
    mainmenu,
    jumpChild,
    isAmin,
    url,
    page,
    linkType,
    isCollapse = true,
    emit,
  } = props;
  const [menuData, $menuData] = useState<MenuType[]>([]);
  const requestMenu = useGetMenuTreeEffect();
  const history = useInbizRouter();
  const params: any = useParams();
  const [inbizMenuList, $inbizMenuList] = useShareDataFlow<MenuType[]>('inbiz-menu-data-list');
  const defaultLogo = globalAppInfo?.inbizLogo || logo;
  const levelLength = showLevel?.length;
  const notshowMenuByLevel = levelLength < 1;//没有选择展示菜单
  const showMenuByLevel = levelLength >= 1;//没有选择展示菜单
  const showOneLevel = showMenuByLevel && showLevel.includes('1');//是否包含展示一级
  const showSecLevel = showMenuByLevel && showLevel.includes('2');//是否包含展示二级 
  const sendMenuMsg = (menuData: MenuType[]) => {
    menuData.map((item: MenuType) => {
      const pageRouter = params?.pageRouter;
      const oneLevelRoute = pageRouter === 'page' ? params.childRouter : pageRouter;
      if (item?.Route === oneLevelRoute) {
        item.isSelect = true;
        if (!item.JumpRoute) {
          item.JumpRoute = item.Route;
        }
        //暂时处理
        // 只展示1级
        const isSelectOne = showLevel?.length === 1 && showLevel[0] === '1';
        if (props?.emit && isSelectOne) {
          props?.emit('onvmenu', {
            OutId: item.OutId,
            Route: item.Route,
            JumpRoute: item.JumpRoute,
          });
        }
      }
    });
  };

  // useEffect(() => {

  //   // 在设计页，非主菜单应该清空
  //   if (getEditor() && !mainmenu) {
  //     $menuData([]);
  //     return
  //   }

  //   // 在设计页，没有勾选展示一级应该清空
  //   if (getEditor() && !showOneLevel) {
  //     $menuData([]);
  //     return
  //   }

  //   // 是否存菜单在共享数据
  //   if (inbizMenuList?.length > 0) {
  //     $menuData(inbizMenuList);
  //     return;
  //   }

  //   // 主菜单获取顶级列表
  //   if (mainmenu) {
  //     requestMenu((res: MenuType[]) => {
  //       $inbizMenuList(res)
  //       $menuData(res);
  //     });
  //     return;
  //   }


  //   if (!mainmenu && linkcomponent) {
  //     const inbizMenuListener = props?.inbiz(linkcomponent);
  //     if (inbizMenuListener) {
  //       inbizMenuListener.on('vmenu', (menu: MenuType[]) => {
  //         if (Array.isArray(menu)) {
  //           $menuData(menu);
  //           return;
  //         }

  //         requestMenu((res: MenuType[]) => {
  //           res = res.map((item: any) => {
  //             if (!item.JumpRoute) {
  //               item.JumpRoute = item.Route;
  //             }
  //             item.JumpRoute = `${menu.JumpRoute}/${item.JumpRoute}`;
  //             return item;
  //           });
  //           $menuData(res);
  //         }, menu.Route);
  //       })
  //     } else {

  //     }
  //   }

  //   return () => {
  //     props?.inbiz(linkcomponent)?.off('vmenu');
  //   }

  //   // requestMenu((res: any) => {
  //   //   $menuData(res);
  //   // }, params?.pageRouter);

  // }, [mainmenu, inbizMenuList, showOneLevel, linkcomponent]);

  // 初次数据渲染
  useEffect(() => {
    if (!mainmenu && !getEditor()) {
      return;
    }

    if (mainmenu) {
      if (menuData.length > 0 && !getEditor()) {
        sendMenuMsg(menuData);
        return;
      }
      if (showLevel?.length > 0) {
        if (showLevel[0] === '1') {
          requestMenu((res: any) => {
            sendMenuMsg(res);
            $menuData(res);
          });
        } else {
          $menuData([]);
        }
      } else {
        $menuData([]);
      }
    } else {
      $menuData([]);
    }
  }, [mainmenu, showLevel, params]);

  // 用于菜单接收主菜单发的事件
  useEffect(() => {
    if (!mainmenu) {
      props?.inbiz(linkcomponent)?.on('vmenu', (menu: MenuType[]) => {
        if (Array.isArray(menu)) {
          $menuData(menu);
          return;
        }

        requestMenu((res: MenuType[]) => {
          res = res.map((item: any) => {
            if (!item.JumpRoute) {
              item.JumpRoute = item.Route;
            }
            item.JumpRoute = `${menu.JumpRoute}/${item.JumpRoute}`;
            return item;
          });
          $menuData(res);
        }, menu.OutId);
      });
    }
    return () => {
      props?.inbiz(linkcomponent)?.off('vmenu');
    };
  }, [mainmenu]);

  /**
   * 顶级菜单处理函数
   *@data 一级菜单的所有值
   */
  const topHoverChange = (data: MenuType[]) => {
    let newData: MenuType[] = [];
    data.forEach((item: any) => {
      if (item.OutId != 'more') {
        newData.push(item);
      } else {
        newData = newData.concat(item.children);
      }
    });
    $menuData(newData);
  };

  const [inlineCollapsed, $inlineCollapsed] = useInlineCollapsed();

  // 菜单参数集
  const menuProps = {
    menuData: {
      val: menuData,
      set: topHoverChange,
    },
    viewtype,
    logoconfig,
    showlogo,
    showLevel,
    displaytype,
    shrinkage,
    mainmenu,
    menustyle,
    jumpChild,
    inlineCollapsed,
    url,
    page,
    isCollapse,
    linkType,
    emit,
    inbiz: props.inbiz
  };

  useEffect(() => {
    $inlineCollapsed(displaytype == 'shrink');
  }, [displaytype]);

  const isMenu = inlineCollapsed && menuData.length >= 1;

  useEffect(() => {
    changeAmin(isAmin, isMenu);
  }, [isAmin, isMenu]);

  return menuData.length >= 1 || getEditor() ? (
    <div
      className={'vertical-menu'}
      style={{
        width: inlineCollapsed ? '50px' : '180px',
      }}
    >
      <Logo
        showlogo={showlogo}
        logoconfig={logoconfig}
        defaultLogo={defaultLogo}
        smallLogoconfig={smallLogoconfig}
        onClick={() => {
          openUrl(props, history);
        }}
      />
      <Vertical {...menuProps} />
      <div
        className={
          inlineCollapsed ? 'vertical-menu-bottom' : 'vertical-menu-bottom-inlineCollapsed'
        }
      >
        {
          <div
            style={{
              display: inlineCollapsed ? 'none' : 'block',
              width: props.plugin ? '100%' : 'inherit',
            }}
          >
            <Plugin>
              <RenderDropableWidget node={props.plugin} pluginName="VerticalMenu.Plugin" />
            </Plugin>
          </div>
        }
        {shrinkage && <InlineCollapsedIcon />}
      </div>
    </div>
  ) : null;
});

const InlineCollapsedIcon = observer(() => {
  const [inlineCollapsed, $inlineCollapsed] = useInlineCollapsed();
  return (
    <div
      className="inlineCollapsed-icon"
      onClick={() => {
        $inlineCollapsed(!inlineCollapsed);
      }}
    >
      <InbizIcon
        type={inlineCollapsed ? 'icon-ic-zhankai1' : 'icon-ic-shousuo'}
        style={{ fontSize: '20px' }}
      />
    </div>
  );
});

const Logo = observer(
  (props: {
    showlogo: boolean;
    logoconfig?: string;
    smallLogoconfig?: string;
    onClick: any;
    defaultLogo: string;
  }) => {
    const { showlogo, logoconfig, smallLogoconfig, defaultLogo } = props;
    const [inlineCollapsed] = useInlineCollapsed();

    return (
      <>
        {showlogo && !inlineCollapsed && (
          <div className="logo" onClick={props.onClick}>
            <img
              className="upload-logo"
              src={
                logoconfig ? `${logoconfig.replace('{AppId}', globalAppInfo.AppId)}` : defaultLogo
              }
            />
          </div>
        )}

        {showlogo && inlineCollapsed && (
          <div className="small-logo" onClick={props.onClick}>
            <img
              className="upload-logo"
              src={
                smallLogoconfig
                  ? `${smallLogoconfig.replace('{AppId}', globalAppInfo.AppId)}`
                  : defaultSmall
              }
            />
          </div>
        )}
      </>
    );
  },
);

export const Plugin = observer(({ children, ...props }) => {
  const rightBox = useLayouts('VerticalMenu.Plugin');
  const isPreview = rightBox && rightBox.length && rightBox.length > 0 && rightBox[0].props;
  const pluginProps = isPreview || props;
  const style = {
    display: 'flex',
    minHeight: 60,
    overflow: 'auto',
    flexDirection: pluginProps.direction || 'row',
    justifyContent: pluginProps.direction == 'row' ? pluginProps.align || 'center' : 'center',
    alignItems: pluginProps.direction !== 'row' ? pluginProps.align || 'center' : 'center',
  };

  if (rightBox && rightBox[0]?.schema.properties) {
    style['minWidth'] = 149;
  }
  return (
    <div
      style={{
        ...style,
        ...props.style,
      }}
    >
      {children}
    </div>
  );
});

VerticalMenu.Plugin = Plugin;

export default VerticalMenu
